package com.ksyun.campus.metaserver.util;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.ksyun.campus.metaserver.entity.server.DataServer;
import com.ksyun.campus.metaserver.entity.server.MetaServer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.ZooKeeper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * ZooKeeper工具类
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ZooKeeperUtil {
    @Getter
    private final ZooKeeper zooKeeper;
    @Value("${zk.metaServerRootPath}")
    public String ZK_META_SERVER_ROOT_PATH;
    @Value("${zk.dataServerRootPath}")
    public String ZK_DATA_SERVER_ROOT_PATH;


    /**
     * 根据服务根路径获取所有注册的dataServer节点信息
     *
     * @return 服务列表
     */
    public List<DataServer> getDataServerlist(String serverRootPath) {
        List<DataServer> serverList = new ArrayList<>();
        try {
            List<String> children = zooKeeper.getChildren(serverRootPath, false);
            for (String child : children) {
                byte[] data = zooKeeper.getData(serverRootPath + "/" + child, false, null);
                String serverInfo = new String(data, StandardCharsets.UTF_8);
                DataServer dataServer = JSON.parseObject(serverInfo, DataServer.class);
                serverList.add(dataServer);
            }
        } catch (Exception e) {
            log.error("获取服务列表失败", e);
        }
        return serverList;
    }

    /**
     * 根据服务根路径获取所有注册的 metaServer节点信息
     *
     * @return 服务列表
     */
    public List<MetaServer> getMetaServerlist(String serverRootPath) {
        List<MetaServer> serverList = new ArrayList<>();
        try {
            List<String> children = zooKeeper.getChildren(serverRootPath, false);

            for (String child : children) {
                byte[] data = zooKeeper.getData(serverRootPath + "/" + child, false, null);
                String serverInfo = new String(data, StandardCharsets.UTF_8);
                MetaServer metaServer = JSON.parseObject(serverInfo, MetaServer.class);
                serverList.add(metaServer);
            }
        } catch (Exception e) {
            log.error("获取服务列表失败 [msg]: {}", e.getMessage());
        }
        return serverList;
    }

    /**
     * 获取当前服务的节点
     *
     * @param serverPort 当前服务的端口号
     * @return zk中的当前服务的节点
     */
    public MetaServer getCurMetaServer(Integer serverPort) {
        List<MetaServer> metaServerlist = getMetaServerlist(ZK_META_SERVER_ROOT_PATH);
        return metaServerlist
                .stream()
                .filter(each -> each.getPort().equals(serverPort))
                .findFirst()
                .orElse(null);
    }

    /**
     * 判断从节点是否还活着
     *
     * @param masterServerPort 当前主节点的端口号
     * @return 是否活着
     */
    public Boolean isSlaveAlive(Integer masterServerPort) {
        List<MetaServer> metaServerlist = getMetaServerlist(ZK_META_SERVER_ROOT_PATH);
        MetaServer metaServer = metaServerlist.stream()
                .filter(each -> !each.getPort().equals(masterServerPort))
                .findFirst()
                .orElse(null);
        return ObjectUtil.isNotNull(metaServer);
    }

    /**
     * 获取主节点
     *
     * @return 主节点实体
     */
    public MetaServer getMaster() {
        List<MetaServer> metaServerlist = getMetaServerlist(ZK_META_SERVER_ROOT_PATH);
        return metaServerlist.stream()
                .filter(each -> Boolean.TRUE.equals(each.getIsMaster()))
                .findFirst()
                .orElse(null);
    }
}
